/*
 * Canvas Game Library
 * 
 * Copyright Chainsawrus Wreaks 2011
 * All rights reserved.
 */

/**
 * @fileOverview The Canvas Game Library is a simple library to make JS gameprogramming a bit less bothersome.
 * It's mostly for the new HTML5 standard working with the <canvas> tag as a graphics container.
 * I will try to make it as whole as possible, it's mostly a training excersise, but I hope to find some future use for it as well.
 * At first I want to write basic implementation for content and asset control, but I also want a good working communication library to handle server page scripts and database queries.
 * I would also like to write a good Entity class to take care of elements of the game as well as basic 2d physics and collision detection.
 * At first I will build this library with the Cthulhu Breaker port in mind, making it a pretty straight forward project as on what tools I need to implement into the library.
 * @todo Image loader class, dynamically load images and store them in a hidden <div>
 * @todo Resource Management through XML and Ajax, Make a resource loader that utilizes ajax function and gets a XML file with asset src and info.
 * @todo Basic Entity class, a class to create and work with game entities.
 * @todo Basic Entity collision detection and control, a set of functions that checks for and manages collisions.
 * @todo Basic Input event manager, a class to handle input from keyboard and mouse, and ingame events such as Collisions.
 * @todo Sprite management, a class to load and manage sprites, give the different sprites id and in the future manage a AnimateSprite function.
 * @name cgl.0.1.js
 */

/**
 * The CGL global namespace Object.
 * @namespace CGL
 */

var CGL = {};

/**
 * @class CGL.canvas
 * @global DEFAULT_CONTEXT : The Context that the canvas draws on.
 * @global DEFAULT_CANVAS_ID : The DOM id that will be appointed to the canvas element.
 * @global CANVAS_CONTAINER : The container that the canvas will be put into.
 * @global CANVAS_WIDTH : The width of the canvas.
 * @global CANVAS_HEIGHT : The height of the canvas.
 * @global TARGET_FPS : The framerate the canvas will try to target.
 * 
 * @function setDefault : Set a default parameter
 *  
 * @description The class that controls and creates the canvas where the game graphics will be rendered.
 */
CGL.canvas = {
	DEFAULT_CONTEXT : "2d",
	DEFAULT_CANVAS_ID : "cglcanvas",
	CUSTOM_CURSOR : false,
	CUSTOM_CURSOR_URL : "",
	HIDE_STATUS : false,
	
	CANVAS_CONTAINER : "",
	CANVAS_WIDTH : 300,
	CANVAS_HEIGHT : 200,
	TARGET_FPS : 120,

	/**
	 * @function setDefault(option, value)
	 * @description Sets the value of the option specified
	 */
	setDefault : function(option, value){
		CGL.canvas[option] = value;
	},

	/**
	 * @function getDefault(option)
	 * @returns The value of the option
	 */
	getDefault : function(option){
		return CGL.canvas[option];
	},
	
	/**
	 *  @method createCanvas(id, width, height)
	 *  @param id : sets the CANVAS_CONTAINER
	 *  @param width : sets the CANVAS_WIDTH
	 *  @param height : sets the CANVAS_HEIGHT
	 *  
	 *  Creates a <canvas> element that will be used as the main graphics container for the game!
	 */
	createCanvas : function(id, width, height){
		
		var canvas = document.createElement("canvas");
		
		CGL.canvas.CANVAS_WIDTH = width;
		CGL.canvas.CANVAS_HEIGHT = height;
		CGL.canvas.CANVAS_CONTAINER = id;
		
		canvas.setAttribute("width", width);
		canvas.setAttribute("height", height);
		canvas.style.borderColor = "black";
		canvas.style.borderStyle = "solid";
		canvas.style.borderWidth = "1px";
		if(CGL.canvas.CUSTOM_CURSOR)
		{
			canvas.style.cursor = "url(" + CGL.canvas.CUSTOM_CURSOR_URL + "), auto";
		}
		canvas.setAttribute("id", CGL.canvas.DEFAULT_CANVAS_ID);
		
		document.getElementById(id).appendChild(canvas);
		
		var elem = document.createElement("div");
		elem.setAttribute("id", "status");
		elem.style.width = width + "px";
		elem.style.height = "120px";
		elem.style.overflowY = "scroll";
		elem.style.borderColor = "black";
		elem.style.borderStyle = "solid";
		elem.style.borderWidth = "1px";
		elem.style.color = "black";
		elem.style.backgroundColor = "white";
		elem.style.fontSize = "10px";
		elem.style.fontWeight = "normal";
		if(CGL.canvas.HIDE_STATUS)
		{
			elem.style.display = "none";
		}
		document.getElementById(id).appendChild(elem);
	},
	
	/**
	 * @method getContext()
	 * 
	 * @returns the graphic context as chosen by the DEFAULT_CONTEXT global.
	 */
	getContext : function(){
		var canvas = document.getElementById(CGL.canvas.DEFAULT_CANVAS_ID);
		return canvas.getContext(CGL.canvas.DEFAULT_CONTEXT);
	}
};

/**
 * @class util
 * 
 * @description A collection of functions and globals that itegrate closely with the general game engine.
 * 
 * @todo A Image and Audio resource loader that will be the basis for loading indicators.
 * @todo Game timer that will send live data to the update function of the game to drive such things as animation and entities.
 */
CGL.util = {
	
	MESSAGE_ID : 0,
	LASTUPDATE : 0,
	UPDATE_RPS : 5,
	FPS : 0,
	FRAMES : 0,
	COOLDOWN_DELAY : 1000,
	
	
	printLn : function(message) {
		var elem = document.createElement("p");
		elem.setAttribute("id", CGL.util.MESSAGE_ID);
		document.getElementById("status").appendChild(elem);
		document.getElementById(CGL.util.MESSAGE_ID).innerHTML = CGL.util.MESSAGE_ID + " : " + message;
		CGL.util.MESSAGE_ID++;
	},
	
	gameTimer : function() {
		var delta = new Date();
		if(delta.getTime() > CGL.util.LASTUPDATE + 1000/CGL.util.UPDATE_RPS)
		{
			CGL.util.LASTUPDATE = delta.getTime();
			return true;
		}
		else
		{
			return false;
		}
	},
	
	showFps : function(ctx, x, y) {
		var fps, delta;
		delta = new Date();
		if(delta.getTime() - CGL.util.LASTUPDATE > 1000)
		{
			CGL.util.FPS = CGL.util.FRAMES;
			CGL.util.FRAMES = 0;
			CGL.util.LASTUPDATE = delta.getTime();
		}
		else
		{
			CGL.util.FRAMES++;
		}
		ctx.save();
		ctx.textAlign = "left";
		ctx.font = "Bold 10px Verdana";
		if(x == undefined || y == undefined)
		{
			ctx.fillText("FPS: " + CGL.util.FPS, 10, 20);
		}
		else
		{
			ctx.fillText("FPS: " + CGL.util.FPS, x, y);
		}
		ctx.restore();
	},
	
	showFpsGl : function(font, x, y) {
		var fps, delta;
		delta = new Date();
		if(delta.getTime() - CGL.util.LASTUPDATE > 1000)
		{
			CGL.util.FPS = CGL.util.FRAMES;
			CGL.util.FRAMES = 0;
			CGL.util.LASTUPDATE = delta.getTime();
		}
		else
		{
			CGL.util.FRAMES++;
		}
		
		if(x == undefined || y == undefined)
		{
			font.drawString("FPS: " + CGL.util.FPS, 10, 10);
		}
		else
		{
			font.drawString("FPS: " + CGL.util.FPS, x, y);
		}
	},
	
	coolDown : function(cooltime) {
		var delta = new Date();
		if(delta.getTime() > cooltime + CGL.util.COOLDOWN_DELAY)
		{
			return true;
		}
		else
		{
			return false;
		}
	},
	
	getGameTime : function() {
		var delta = new Date();
		return delta.getTime();
	}
};

CGL.resources = {
	RESOURCES_IMAGES : 0,
	RESOURCES_AUDIO : 0,
	LOADED_IMAGES : 0,
	LOADED_AUDIO : 0,
	
	addImageResource : function() {
		CGL.resources.RESOURCES_IMAGES++;
	},
	
	addAudioResource : function() {
		CGL.resources.RESOURCE_AUDIO++;
	},
	
	notifyLoadedImage : function() {
		CGL.resources.LOADED_IMAGES++;
		CGL.util.printLn("Loaded: " + CGL.resources.getLoadingIndication() + " " + CGL.resources.RESOURCES_IMAGES + "/" + CGL.resources.LOADED_IMAGES);
	},
	
	notifyLoadedAudio : function() {
		CGL.resources.LOADED_AUDIO++;
	},
	
	getLoadingIndication : function() {
		return Math.ceil(100/(CGL.resources.RESOURCES_IMAGES) * CGL.resources.LOADED_IMAGES);
	},
	
	getFinishedLoading : function() {
		if(CGL.resources.LOADED_IMAGES == CGL.resources.RESOURCES_IMAGES)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
};